<template>
  <div id="api-management" class="api-management innerPageTable-box-OneTwo">
    <div id="dragBox" class="drag-wrap">
      <div id="drag-left">
        <div class="title">API分组</div>

        <!-- highlight-current -->
        <!-- 
                    lazy
                    :load="loadData" -->
        <el-tree
          :data="treeData"
          ref="apiTree"
          lazy
          :load="loadData"
          :props="defaultProps"
          :expand-on-click-node="false"
          icon-class="ivu-icon-ios-arrow-forward"
          node-key="id"
          @node-click="handleNodeClick"
        >
          <div class="custom-tree-node" slot-scope="{ node, data }">
            <span class="custom-node-lable">{{ node.label }}</span>
            <div class="operate-bar">
              <Tooltip :content="$t('common.add')" transfer placement="top">
                <Button type="text" @click.stop="addGroup(node, data)">
                  <Icon type="md-add"></Icon>
                </Button>
              </Tooltip>
              <Dropdown
                trigger="custom"
                placement="bottom-start"
                @on-click="
                  $event => {
                    treeMoreChange($event, node, data)
                  }
                "
                :visible="isVisibleNodeId == data.id"
                transfer
              >
                <Tooltip :content="$t('common.more')" transfer placement="top">
                  <Button type="text" @click.stop="onMore(data)">
                    <Icon type="ios-more"></Icon>
                  </Button>
                </Tooltip>
                <template #list>
                  <DropdownMenu>
                    <DropdownItem name="details">详情</DropdownItem>
                    <DropdownItem :disabled="node.level === 1" name="delete">删除</DropdownItem>
                  </DropdownMenu>
                </template>
              </Dropdown>
            </div>
          </div>
        </el-tree>
      </div>
      <div id="resize-line"></div>
      <div id="drag-right">
        <div class="title">
          {{ currentNode.path }}
        </div>
        <div style="height: calc(100% - 54px)">
          <div class="apiManagement-innerPageTable">
            <!-- 搜索区域 -->
            <SelfAdaption>
              <Form
                :model="formSearch"
                ref="apiManagementFormSearch"
                slot="adaption-bar"
                class="ivu-form-no-margin-bottom"
                inline
              >
                <template>
                  <!-- 接口描述 -->
                  <Form-item prop="apiDesc" :label="$t('module.apiManage.interfaceDescription')">
                    <Input
                      type="text"
                      v-model.trim="formSearch.apiDesc"
                      :placeholder="$t('module.apiManage.placeholder.interfaceDescription')"
                      :maxlength="30"
                      @on-enter="search"
                    />
                  </Form-item>

                  <!-- 接口地址 -->
                  <Form-item prop="apiPath" :label="$t('module.apiManage.interfaceAddress')">
                    <Input
                      type="text"
                      v-model.trim="formSearch.apiPath"
                      :placeholder="$t('module.apiManage.placeholder.interfaceAddress')"
                      :maxlength="30"
                      @on-enter="search"
                    />
                  </Form-item>
                  <!-- 请求方式 -->
                  <Form-item prop="requestMethod" :label="$t('module.apiManage.requestMethod')">
                    <Select
                      v-model="formSearch.requestMethod"
                      style="width: 100%"
                      :placeholder="$t('module.apiManage.placeholder.requestMethod')"
                      clearable
                    >
                      <Option value="GET">GET</Option>
                      <Option value="POST">POST</Option>
                      <Option value="PUT">PUT</Option>
                      <Option value="DELETE">DELETE</Option>
                    </Select>
                  </Form-item>
                  <!-- 状态 -->
                  <Form-item prop="enabled" :label="$t('common.status')">
                    <Select
                      v-model="formSearch.enabled"
                      style="width: 100%"
                      :placeholder="$t('common.warning.selectStatus')"
                      clearable
                    >
                      <Option :value="0">{{ $t('common.disable') }}</Option>
                      <Option :value="1">{{ $t('common.enable') }}</Option>
                    </Select>
                  </Form-item>
                  <!-- 查询\重置按钮 -->
                  <Form-item prop="button" class="search-solt-btn">
                    <RPButton optType="search" @click="search" />
                    <RPButton optType="reset" @click="formReset" />
                  </Form-item>
                </template>
              </Form>
            </SelfAdaption>
            <InnerPageTable ref="apiManagementTable" :config="tableConfig">
              <div slot="table-bar">
                <RPButton optType="create" @click="addApi()" />
                <RPButton
                  optType="create"
                  text="swagger初始化"
                  v-show="currentNode.parentId == null"
                  @click="addApiBySwagger()"
                />
                <RPButton optType="batch" text="批量删除" @click="onDelApi('batch')" />
              </div>
            </InnerPageTable>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { apiManagementColumns } from './columns.js'
import { apiGroup } from '@/api/apiManagement.js'
import addApi from './addApi.vue'
import addApiGroup from './addApiGroup.vue'
import AddApiBySwagger from './addApiBySwagger.vue'
export default {
  name: 'api-management',
  data() {
    return {
      resizeBox: null,
      parentBox: null,
      dragLeft: null,
      startX: 0,
      treeData: [],
      defaultProps: {
        children: 'children',
        label: 'path'
      },
      isVisibleNodeId: null,
      currentNodeId: null,
      currentNode: {},
      formSearch: {
        apiDesc: '',
        apiPath: '',
        requestMethod: '',
        enabled: '',
        groupPath: ''
      },
      tenantCode: $store.state['ripples-components'].userInfo.tenantCode
    }
  },
  created() {
    this.getApiGroupRoot()
  },
  computed: {
    tableConfig() {
      return { loadDataFn: this.getApiManagementList, columnsFn: apiManagementColumns.bind(this) }
    }
  },
  watch: {
    isVisibleNodeId(val) {
      if (val !== null) {
        window.addEventListener('click', this.clickoutside, false)
      } else {
        window.removeEventListener('click', this.clickoutside)
      }
    }
  },
  mounted() {
    this.dragControllerDiv()
    // this.$refs["apiTree"].setCurrentKey(this.currentNode.id);
  },
  destroyed() {
    this.clickoutside()
    window.removeEventListener('click', this.clickoutside)
  },
  deactivated() {
    this.clickoutside()
    window.removeEventListener('click', this.clickoutside)
  },
  methods: {
    // 根据分组路径获取api
    getApiManagementList({ responseProcess, param }) {
      $http.post(`${window.RPConfig.mgt}/api/getApiByGroupPath`, param).then(res => {
        // 状态为有效：禁用复选框，不可删除
        let { records } = res.data
        records = this.$root.$options.filters['selection-disabled'](records)
        responseProcess(res.data)
      })
    },
    // 获取分组根目录
    getApiGroupRoot() {
      const self = this
      apiGroup.getApiGroupRoot({ tenantCode: this.tenantCode }).then(res => {
        this.treeData = res.data
        if (this.treeData.length > 0) {
          this.currentNode = this.treeData[0]
          this.handleNodeClick(this.currentNode)
          this.$nextTick(() => {
            self.$refs['apiTree'].setCurrentKey(self.treeData[0].id)
          })
        }
      })
    },
    loadData(node, resolve) {
      if (node.level == 0) {
        // 隐藏根节点
        return
      }
      // 是叶子节点不进行查询
      if (node.isLeaf) {
        resolve([])
      }
      apiGroup
        .getApiGroupByParentId({ parentId: node.data.id, routeId: node.data.routeId })
        .then(children => {
          resolve(children.data)
        })
        .catch(() => {
          resolve([])
          node.expanded = false
          node.isLeaf = false
          node.loaded = false
        })
    },
    search(page = 1) {
      this.$refs['apiManagementTable'].load(Object.assign({ apiConditionVo: this.formSearch }, this.formSearch), page)
    },
    formReset() {
      this.$refs['apiManagementFormSearch'].resetFields()
      this.search()
    },
    onMore(data) {
      this.isVisibleNodeId = data.id
    },
    clickoutside() {
      this.isVisibleNodeId = null
    },
    dragControllerDiv() {
      this.resizeBox = document.getElementById('resize-line') // 拖拽条
      this.parentBox = document.getElementById('dragBox') // 父盒子

      this.dragLeft = document.getElementById('drag-left')
      // 拖拽条添加事件
      this.resizeBox.addEventListener('mousedown', this.onMouseDown)
    },
    onMouseDown(e) {
      this.clickoutside()
      //颜色改变提醒
      this.resizeBox.style.userSelect = 'none'
      this.dragLeft.style.userSelect = 'none'
      this.resizeBox.style.background = '#FF6F4B'
      this.resizeBox.style.width = '2px'
      this.startX = e.clientX
      this.resizeBox.left = this.resizeBox.offsetLeft

      document.addEventListener('mousemove', this.onMousemove)
      document.addEventListener('mouseup', this.onMouseup)
    },
    onMousemove(e) {
      const endX = e.clientX
      let moveLen = this.resizeBox.left + (endX - this.startX) // （endx-startx）=移动的距离。resize.left+移动的距离=左边区域最后的宽度
      if (moveLen < 248) moveLen = 248 // 左边区域的最小宽度为248px
      if (moveLen > 500) moveLen = 500 // 左边区域的最大宽度为500px

      this.resizeBox.style.left = moveLen
      const dragRight = document.getElementById('drag-right')
      this.dragLeft.style.width = moveLen + 'px' // 设置左侧区域的宽度
      dragRight.style.width = this.parentBox.clientWidth - moveLen - 2 + 'px'
    },
    onMouseup() {
      // 颜色恢复
      this.resizeBox.style.background = '#E2E4EA'
      this.resizeBox.style.width = '1px'
      this.resizeBox.style.userSelect = 'unset'
      this.dragLeft.style.userSelect = 'unset'
      document.removeEventListener('mousedown', this.onMouseDown)
      document.removeEventListener('mousemove', this.onMousemove)
      document.onmousemove = null
      document.onmouseup = null
      this.resizeBox.releaseCapture && this.resizeBox.releaseCapture()
    },
    //
    handleNodeClick(data) {
      this.isVisibleNodeId = null
      this.formSearch.groupPath = data.path

      if (this.currentNode.id !== data.id) {
        this.formReset()
      } else {
        this.search()
      }
      this.currentNode = data
    },
    // 添加分组子节点
    addGroup(node, data) {
      this.currentRootNode = this.findRootNode(node)
      this.clickoutside()
      new this.$pageModal(
        addApiGroup,
        {
          props: {
            tenantCode: this.tenantCode,
            apiGroupInfo: data,
            currentRootNode: this.currentRootNode
          }
        },
        data => {
          if (!data || node.level == 0 || !node.expanded) {
            return false
          }
          apiGroup.getApiGroupByParentId({ parentId: node.data.id, routeId: node.data.routeId }).then(children => {
            this.refreshLazyTree(node, children.data)
          })
        }
      )
    },
    // 更多
    treeMoreChange(name, node, data) {
      if (name === 'delete') {
        this.onRemove(node, data)
      } else {
        this.onDetail(data)
      }
    },
    // 删除分组节点
    onRemove(node, data) {
      const parent = node.parent
      new $confirm(this.$t('common.warning.confirmDelete'), this).then(() => {
        apiGroup.deleteApiGroupById({ id: node.data.id }).then(children => {
          this.$message.success({
            content: this.$t('common.deleteSuccess'),
            duration: 3
          })
          apiGroup.getApiGroupByParentId({ parentId: parent.data.id, routeId: parent.data.routeId }).then(children => {
            this.refreshLazyTree(parent, children.data)
          })
        })
      })
    },
    // 刷新操作节点的数据
    refreshLazyTree(node, children) {
      const theChildren = node.childNodes
      theChildren.splice(0, theChildren.length)
      node.doCreateChildren(children)
      if (children.length < 1) {
        node.isLeaf = true
      }
    },
    // 根据当前节点获取根节点
    findRootNode(node) {
      let rootNode = node
      if (node.level === 1) {
        return rootNode.data || {}
      }
      if (rootNode.parent) {
        return this.findRootNode(rootNode.parent)
      }
      return rootNode.data || {}
    },
    getSelectedIds() {
      let list = this.$refs['apiManagementTable'].getSelectioned() || []
      let ids = []
      for (let u of list) {
        ids.push(u.id)
      }
      return ids
    },
    // 删除API
    onDelApi(type, data) {
      let ids = ''
      if (type === 'single') {
        ids = data.id
      } else {
        ids = this.getSelectedIds().join(',')
      }
      if (ids === '') {
        this.$message.error({
          content: this.$t('common.warning.selctElement'),
          duration: 3
        })
        return
      }
      new $confirm(this.$t('common.warning.confirmDelete'), this).then(() => {
        apiGroup.deleteApiByIds({ ids }).then(res => {
          this.$message.success({
            content: this.$t('common.deleteSuccess'),
            duration: 3
          })
          this.search()
        })
      })
    },
    // 查看详情
    onDetail(row) {
      this.$router.push({
        path: '/domain-manage/api-management/detail',
        query: {
          detailInfo: JSON.stringify(row)
        }
      })
      console.log('apiInfo', row)
    },
    // 新增api
    addApi() {
      new this.$pageModal(
        addApi,
        {
          props: {
            tenantCode: this.tenantCode,
            apiGroupInfo: this.currentNode
          }
        },
        data => {
          if (data) {
            this.search()
          }
        }
      )
    },
    addApiBySwagger() {
      new this.$pageModal(
        AddApiBySwagger,
        {
          props: {
            tenantCode: this.tenantCode,
            apiGroupInfo: this.currentNode
          }
        },
        data => {
          if (data) {
            this.search()
          }
        }
      )
    },
    // api编辑
    onApiEdit(row) {
      new this.$pageModal(
        addApi,
        {
          props: {
            tenantCode: this.tenantCode,
            apiGroupInfo: this.currentNode,
            apiInfo: row,
            dialogType: 'edit'
          }
        },
        data => {
          if (data) {
            this.search()
          }
        }
      )
    }
  }
}
</script>
<style lang="less">
.single-page {
  &:has(#api-management) {
    padding: 6px 0px;
  }
}
</style>
<style lang="less" scoped>
.api-management {
  .drag-wrap {
    position: relative;
    display: flex;
    width: 100%;
    height: 100%;
    #drag-left {
      width: 248px;
      padding: 0 8px;
      .title {
        height: 50px;
        line-height: 50px;
        font-size: 16px;
        color: #111a34;
        font-weight: 500;
        padding-left: 10px;
      }
      .el-tree {
        height: calc(100% - 50px);
        overflow: hidden;
        /deep/.el-tree-node {
          &:focus {
            > .el-tree-node__content {
              background-color: inherit;
            }
          }
          .el-tree-node__children {
            .el-tree-node__expand-icon {
              &.is-leaf {
                min-width: 24px;
                min-height: 24px;
                &::before {
                  content: '';
                  display: inline-block;
                  width: 4px;
                  height: 4px;
                  border-radius: 50%;
                  background: #a3aabe;
                }
              }
            }
            .el-tree-node__content {
              &:hover {
                .el-tree-node__expand-icon {
                  &.is-leaf {
                    &::before {
                      background: #a3aabe;
                    }
                  }
                }
              }
            }
            .is-current {
              &.el-tree-node {
                > .el-tree-node__content {
                  .el-tree-node__expand-icon {
                    &.is-leaf {
                      &::before {
                        background: var(--primary-color);
                      }
                    }
                  }
                  .ivu-icon {
                    &:hover {
                      background: var(--primary-color-opacity2);
                    }
                  }
                }
              }
            }
          }
          .el-tree-node__content {
            height: 32px;
            margin-bottom: 2px;
            .ivu-icon {
              padding: 3px;
              border-radius: 2px;
            }
            &:hover {
              background-color: var(--tree-content-hover-bg);
              color: var(--tree-content-hover-color);
              .el-tree-node__expand-icon {
                // color: #A3AABE;
                &:not(.is-leaf) {
                  color: #a3aabe;
                }
              }
              .custom-tree-node {
                .operate-bar {
                  display: block;
                }
              }
              .ivu-icon {
                &:hover {
                  border-radius: 2px;
                  background: var(--tree-content-hover-icon-bg);
                }
              }
            }
          }
          &.is-current {
            > .el-tree-node__content {
              background-color: var(--tree-current-bg);
              color: var(--primary-color);
              .ivu-icon {
                color: var(--primary-color);
              }
              &:hover {
                 background-color: var(--primary-color-opacity1);
                 .ivu-icon:hover {
                    border-radius: 2px;
                    background: var(--primary-color-opacity2);
                 }
              }
              .el-tree-node__expand-icon,
              .custom-tree-node {
                &:not(.is-leaf) {
                  color: var(--primary-color);
                }
              }
            }
            // .ivu-icon {
            //   color: #FF6F4B;
            // }
          }
        }
        &:hover {
          overflow-y: auto;
        }
        &::-webkit-scrollbar-thumb {
          border-radius: 3px;
          background: #c5cad5;
        }
        &::-webkit-scrollbar {
          width: 5px;
        }
      }
      .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        padding-right: 8px;
        color: #41485d;
        overflow: hidden;
        .custom-node-lable {
          flex: 1;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        .operate-bar {
          display: none;
          min-width: 38px;
          margin-left: 2px;
          text-align: right;
          .ivu-btn {
            height: 32px;
            padding: 0;
            color: #a3aabe;
          }
        }
      }
    }
    #resize-line {
      /*鼠标移入显示左右箭头*/
      cursor: col-resize;
      width: 1px;
      background-color: #e2e4ea;
      &:hover {
        width: 2px !important;
        background-color: #ff6f4b !important;
      }
    }
    #drag-right {
      padding: 0 18px;
      width: calc(100% - 248px);
      max-width: calc(100% - 248px);
      .title {
        font-family: PingFangSC-Medium;
        height: 42px;
        line-height: 42px;
        font-size: 14px;
        color: #111a34;
        font-weight: 500;
        border-bottom: 1px solid #e1e6f1;
      }
    }
  }
}
</style>
